home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / Infocom64ToDat.lha / Dsk2Infocom.c < prev    next >
C/C++ Source or Header  |  1993-08-31  |  6KB  |  236 lines

  1. /****************************************************************/
  2. /*    "dsk2infocom" converts disk image of Infocom game         */
  3. /*      for the Commodore 64 to a data file which can be        */
  4. /*      used on every computer                                  */
  5. /*                                                              */
  6. /*    v1.0:   April 26, 1993                                    */
  7. /*    v1.0a:  May 24, 1993                                      */
  8. /*                                                              */
  9. /*    Author: Paul David Doherty (h0142kdd@rz.hu-berlin.de)     */
  10. /****************************************************************/
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14.  
  15. #define TRUE 1
  16. #define FALSE 0
  17.  
  18. #define MAXLENGTH 131072        /* longest possible V3 datafile */
  19. /*
  20.    C-64, using tracks 5-16 and 18-35 ->  30 * 17 * 256 = 130560
  21.    Apple II, using tracks 4-35       ->  32 * 16 * 256 = 131072
  22. */
  23.  
  24. struct ids
  25. {
  26.   char *version;
  27.   char type;
  28.   unsigned short id[6];
  29. } vers_ids[] =
  30.  
  31. {
  32.   "A1", 1, 0xf5, 0x60, 0x20, 0xf7, 0x1f, 0x20,
  33.   "A2", 1, 0x00, 0xd0, 0xf5, 0x60, 0x20, 0xf9,
  34. /*
  35.    "A1" and "A2" are version names I just made up...
  36. */
  37.   "B", 2, 0x0f, 0xa8, 0xa6, 0x78, 0x20, 0xba,
  38.   "C", 3, 0xff, 0xa2, 0x0f, 0x20, 0xc9, 0xff,
  39.   "D", 3, 0xdd, 0x27, 0x09, 0x30, 0x99, 0xf0,
  40.   "E", 3, 0xff, 0xa2, 0x00, 0xc9, 0x0a, 0x90,
  41.   "F", 3, 0xa2, 0xef, 0xa0, 0x27, 0xa9, 0x01,
  42.   "G", 3, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x0d,
  43.   "H", 3, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x5d,
  44.   "Unknown", 0, 0, 0, 0, 0, 0, 0
  45. };
  46.  
  47. struct specs
  48. {
  49.   char t4;                      /* track 4 used? */
  50. /*
  51.    tracks 5..16 are always used
  52. */
  53.   char t17;                     /* track 17 used? */
  54.   char t18;                     /* track 18 used? [starts at sec 2] */
  55. /*
  56.    tracks 19..35 are always used
  57. */
  58.   char tr_used;                 /* 16 = 0..15, 17 = 0..16 */
  59. } vers_specs[] =
  60.  
  61. {
  62.   0, 0, 0, 0,                   /* 0 - don't leave it out! */
  63.   TRUE, TRUE, TRUE, 16,         /* 1 */
  64.   FALSE, FALSE, FALSE, 16,      /* 2 */
  65.   FALSE, FALSE, TRUE, 17        /* 3 */
  66. };
  67.  
  68. FILE *infile;
  69. FILE *outfile;
  70.  
  71. char version;
  72. unsigned short checksum;
  73. unsigned short checkedsum = 0;
  74. unsigned long bytecount = 0;
  75. unsigned long filelength;
  76.  
  77. void gotrack (int);
  78. void transtrack (void);
  79. void usage (void);
  80.  
  81. /*******************************************************************/
  82. /*  MAIN function                                                  */
  83. /*******************************************************************/
  84.  
  85. void
  86. main (int argc, char **argv)
  87. {
  88.   int i, j;
  89.   char gv;
  90.   char dummy[30];
  91.   unsigned short act_id[6];
  92.  
  93.   if (--argc != 1)
  94.     usage ();
  95.  
  96.   if ((infile = fopen (argv[argc], "rb")) == NULL)
  97.     {
  98.       printf ("Error: Can't read \"%s\"\n", argv[argc]);
  99.       exit (5);
  100.     }
  101.  
  102.   strcpy (dummy, argv[argc]);
  103.   strcat (dummy, ".dat");
  104.  
  105.   if ((outfile = fopen (dummy, "wb")) == NULL)
  106.     {
  107.       printf ("Error: Can't create \"%s\"\n", dummy);
  108.       exit (5);
  109.     }
  110.  
  111.   fseek (infile, 0x2000, SEEK_SET);
  112.   for (i = 0; i < 6; i++)
  113.     act_id[i] = getc (infile);
  114.  
  115.   i = 0;
  116.  
  117.   do
  118.     {
  119.       gv = version = vers_ids[i].type;
  120.       for (j = 0; j < 6; j++)
  121.         {
  122.           if (act_id[j] != vers_ids[i].id[j])
  123.             version = 0;
  124.         }
  125.       i++;
  126.     }
  127.   while ((gv != 0) && (version == 0));
  128.  
  129.   if (version == 0)
  130.     {
  131.       printf ("%s interpreter\n", vers_ids[--i].version);
  132.       exit (5);
  133.     }
  134.  
  135.   printf ("C-64 Interpreter %s\n", vers_ids[--i].version);
  136.  
  137.   for (i = 4; i <= 35; i++)
  138.     {
  139.       if ((i == 4) && (!(vers_specs[version].t4)))
  140.         continue;
  141.       if ((i == 17) && (!(vers_specs[version].t17)))
  142.         continue;
  143.       if ((i == 18) && (!(vers_specs[version].t18)))
  144.         continue;
  145.  
  146.       gotrack (i);
  147.       if (i == 18)
  148.         fseek (infile, 512, SEEK_CUR);
  149.  
  150.       transtrack ();
  151.     }
  152. }
  153.  
  154. /*******************************************************************/
  155. /*  Function: gotrack                                              */
  156. /*******************************************************************/
  157.  
  158. void
  159. gotrack (int track)
  160. {
  161.   unsigned long pos;
  162.  
  163. /*
  164.    track  1..17:  21 sectors
  165.          18..24:  19
  166.          25..30:  18
  167.          31..35:  17
  168. */
  169.  
  170.   pos = (track - 1) * 21;
  171.   pos = pos - ((track > 18) ? (track - 18) : 0) * 2;
  172.   pos = pos - ((track > 25) ? (track - 25) : 0) * 1;
  173.   pos = pos - ((track > 31) ? (track - 31) : 0) * 1;
  174.  
  175.   fseek (infile, pos * 256, SEEK_SET);
  176. }
  177.  
  178. /*******************************************************************/
  179. /*  Function: transtrack                                           */
  180. /*******************************************************************/
  181.  
  182. void
  183. transtrack (void)
  184. {
  185.   int gotten;
  186.   int j, k;
  187.  
  188.   for (j = 0; j < (vers_specs[version].tr_used); j++)
  189.     {
  190.       for (k = 0; k < 256; k++)
  191.         {
  192.           gotten = getc (infile);
  193.           putc (gotten, outfile);
  194.  
  195.           if (bytecount == 0x1a)
  196.             filelength = gotten * 256;
  197.           if (bytecount == 0x1b)
  198.             {
  199.               filelength = (filelength + gotten) * 2;
  200.               if (filelength == 0)
  201.                 filelength = MAXLENGTH;
  202.             }
  203.  
  204.           if (bytecount == 0x1c)
  205.             checksum = gotten * 256;
  206.           if (bytecount == 0x1d)
  207.             checksum = checksum + gotten;
  208.  
  209.           bytecount++;
  210.  
  211.           if (bytecount > 0x40)
  212.             {
  213.               checkedsum = checkedsum + gotten;
  214.               if (bytecount == filelength)
  215.                 {
  216.                   printf ("Checksum %s\n", (checksum == checkedsum) ? "okay" : "incorrect!");
  217.                   exit (0);
  218.                 }
  219.             }
  220.         }
  221.     }
  222. }
  223.  
  224. /*******************************************************************/
  225. /*  Function: usage                                                */
  226. /*******************************************************************/
  227.  
  228. void
  229. usage (void)
  230. {
  231.   printf ("\nDsk To Infocom V1.0\n");
  232.   printf ("\n");
  233.   printf ("Usage: Dsk2Infocom Filename.\n\n");
  234.   exit (0);
  235. }
  236.